package com.doit.day02

/**
 * 函数也是一段代码逻辑的封装，便于后续的使用
 *
 * 函数在scala中是头等公民
 *
 * => 就是函数声明的标志
 *
 * def 方法声明的标志
 *
 * 函数的本质：函数的本质就是一个接口的实现类对象
 * 函数 可以当做参数传递
 * 可以当做返回值返回
 */
object _03_函数 {
  def main(args: Array[String]): Unit = {

    //你给我一个啥  我给你处理成啥样  函数体的最后一行，代表的是函数的返回值
    //    (函数的参数)=>{ 函数体 }

    //没有名字的函数  我们叫匿名函数    可以服用嘛？
    val add :(Int,Int)=> Int = (a: Int, b: Int) => {
      a + b
    }

    //:(()=>Unit)=> ()=> ()=>Unit
    val aaa = (op:()=>Unit)=>{
          //返回了一个函数  ()=>()=>Unit
      val abc :()=>()=>Unit = ()=> op
      abc
    }

    //函数的类型分为两种写法 Function2[Int,Int,Int]  这叫java的写法
    //scala提供了一种写法，语法糖的写法Function3[Int,Int,Int,Int]
    val getMax:(Int, Int, Int) => Int= (a:Int, b:Int, c:Int)=>{
      var max = a
      if(b>max){max = b}
      if(c>max){max = c}
      max
    }


    val res :(Int,String) => Unit = (a:Int,b:String)=>{
      val res1: Int = a + b.toInt
      println(res1)
    }


    //有几个参数
    //op:(Int,String)=>Int
    //a:String
    //b:Int

    //类型应该怎么写 :((Int,String)=>Int,String,Int)=> Int
    val tt = (op:Function2[Int,String,Int],a:String,b:Int)=>{
      //返回值  他的类型就是返回值的类型
     op(b, a)
    }

    val tt1 = (op:(Int,String)=>Int,a:String,b:Int)=>{
      op(b,a)
    }



    val testFunction = (a:Int)=>{
      println(a)
    }


    getMax(1,2,3)

    add(1,2)


//    val tt:Function3[Function2[Int,String,Int],String,Int,Function2[Int,String,Int]] = (op:(Int,String)=>Int,a:String,b:Int)=>{
//      op.apply(b,a)
//    }




  }
}
